package com.handinfo.uimenu;

import javax.microedition.lcdui.Graphics;

import com.handinfo.engine.GameManager;
import com.handinfo.game.AbstractGameActor;
import com.handinfo.game.ActorRole;
import com.handinfo.util.Tools;

/**
 * 超链接解析类 1：对原有超链接进行完善 2：扩展图片功能 3：精确其坐标
 * 
 * 明确功能 1：占位 2：换行 3：替换文字 4：标记超链接 5：插入图片
 * 
 * @author venizeng
 * 
 */
public abstract class AbsHyperLinker
{
	// 类型
	public static final String TYPE_CONTENT_TAKEPLACE = String.valueOf('~');// 标记占位符号
	public static final String TYPE_CONTENT_CHANGEROW = String.valueOf('`');// 标记换行符
	protected static final String TYPE_REPLACE = "replace";// 替换
	protected static final String TYPE_MARK = "mark";// 标记超链接
	protected static final String TYPE_PIC = "pic";// 标记超链接
	// 替换文字标记
	protected static final char REPLACE_ATT_COLOR = 'c';
	protected static final char REPLACE_ATT_BOLD = 'b';
	// 超链接标记
	protected static final char MARK_ATT_COLOR = 'c';
	protected static final char MARK_ATT_BOLD = 'b';
	protected static final char MARK_ATT_UNDERLINE = 'u';
	protected static final char MARK_ATT_TYPE = 't';
	protected static final char MARK_ATT_ID = 'i';
	// 图片标记
	protected static final char PIC_ATT_ID = 'i';
	// 通用标记
	protected static final char NOR_BRACKET_RIGHT = '>';
	protected static final char NOR_BRACKET_LEFT = '<';
	protected static final char NOR_SLANT_LINE = '/';
	protected static final char NOR_EQUAL = '=';
	protected static final char NOR_BANK = ' ';// 分隔符号
	protected static final char NOR_SYMBOL_COMMA = ',';// 分隔符号
	// 组合标记
	protected static final String combine_replace_start = String.valueOf(NOR_BRACKET_LEFT) + TYPE_REPLACE;// <replace
	protected static final String combine_replace_end = String.valueOf(NOR_BRACKET_LEFT)
			+ String.valueOf(NOR_SLANT_LINE) + TYPE_REPLACE + String.valueOf(NOR_BRACKET_RIGHT);// </replace>
	protected static final String combine_mark_start = NOR_BRACKET_LEFT + TYPE_MARK;// <mark
	protected static final String combine_mark_end = String.valueOf(NOR_BRACKET_LEFT) + String.valueOf(NOR_SLANT_LINE)
			+ TYPE_MARK + NOR_BRACKET_RIGHT;// </mark>
	protected static final String combine_pic_start = NOR_BRACKET_LEFT + TYPE_PIC;// <pic
	protected static final String combine_pic_end = String.valueOf(NOR_BRACKET_LEFT) + String.valueOf(NOR_SLANT_LINE)
			+ TYPE_PIC + String.valueOf(NOR_BRACKET_RIGHT);// </pic>
	// 默认颜色
	protected static final int COLOR_DEFAULT_NPC = 0x00FFFF;
	protected static final int COLOR_DEFAULT_PLAY = 0x0000FF;
	protected static final int COLOR_DEFAULT_ACTORITEM = 0x00ff00;
	protected static final int COLOR_DEFAULT_MAP = 0x00C0FF;
	protected static final int COLOR_DEFAULT_NOR = 0xffffff;
	//
	public static final char URL_NPC = 'n';
	public static final char URL_ACTORITEM = 'i';
	public static final char URL_ENEMY = 'e';
	public static final char URL_MAP = 'm';
	public static final char URL_PLAYER = 'p';
	public static final char URL_WINDOW = 'w';
	public static final char URL_DOWNLOAD = 'x';
	public static final char URL_DEFAULT = 'd';
	// 默认mark的value
	protected static final boolean MARK_VALUE_BOLDER_DEFAULT = false;
	protected static final boolean MARk_VALUE_UNDERLINE_DEFAULT = false;
	protected static final String MARK_VALUE_ID_DEFAULT = null;
	// 方向
	protected final int DIR_UP = -1;
	protected final int DIR_DOWN = -2;
	protected final int DIR_LEFT = -3;
	protected final int DIR_RIGHT = -4;
	// 需解析的类型
	protected static final byte TYPE_INTRE_CHANGEROW = 1;
	protected static final byte TYPE_INTRE_STR_NOR = 2;
	protected static final byte TYPE_INTRE_STR_HYPER = 3;
	protected static final byte TYPE_INTRE_PIC = 4;
	// Var
	private String m_content_copy;// 文本拷贝
	//
	protected int m_relX;// 相对超链接绘制区域的X，平移用
	protected int m_relY;
	public int m_w;// 超链接的显示宽度
	public int m_h;// 超链接的显示高度
	protected int m_index_hyper;// 指向哪一个超链接
	public String m_content;// 操作文本，去除了占位符，替换文字的
	// 外部数据
	protected char[] m_types_hyper;// 超链接类型
	protected String[] m_ids_hyper;
	protected String[] m_contents_hyper;
	// 传入常量值
	protected int m_color_nor_default;// 外部传入普通文字颜色
	protected int H_PRE = UITools.H_PRE;//

	/**
	 * 构建
	 * 
	 * @param str
	 * @param w
	 * @param h
	 * @param color_default
	 */
	public AbsHyperLinker(String str, int w, int h, int color_default)
	{
		m_content_copy = str;
		m_w = w;
		m_h = h;
		m_color_nor_default = color_default;
		init();
	}

	public AbsHyperLinker(String str, int w, int h)
	{
		this(str, w, h, COLOR_DEFAULT_NOR);
	}

	/**
	 * 对当前数据进行初始化
	 */
	private void init()
	{
		// 替换占位
		// 替换 repalce
		String temp = m_content_copy;
		temp = replaceTakenplace(temp);
		temp = replaceContent(temp);
		m_content = temp;
		// 解释数据
		interpretate();
		setTypes();
		setIds();
		setContents();
	}

	/**
	 * 解析方法，将字符串解析成所需的数据
	 */
	protected abstract void interpretate();

	/**
	 * 设置当前字符串解析出来的超链接类型的文字的标签类型
	 */
	protected abstract void setTypes();

	/**
	 * 设置当前字符串解析出来的超链接类型的文字的标签Id
	 */
	protected abstract void setIds();

	/**
	 * 设置当前字符串解析出来的超链接类型的文字的标签内容
	 */
	protected abstract void setContents();

	/**
	 * 创建一个超链接解析类,具有默认的文本颜色
	 * 
	 * @param content
	 * @param w
	 * @param h
	 * @return
	 */
	public static final AbsHyperLinker createHyperLinker(String content, int w, int h)
	{
		return createHyperLinker(content, w, h, COLOR_DEFAULT_NOR);
	}

	/**
	 * 创建一个超链接解析类，并设定默认文本的颜色
	 * 
	 * @param content
	 * @param w
	 * @param h
	 * @param color_default
	 * @return
	 */
	public static final AbsHyperLinker createHyperLinker(String content, int w, int h, int color_default)
	{
		return new ConcreteHyperLinker(content, w, h, color_default);
	}

	/**
	 * 是否是超链接形式字符串
	 * 
	 * @param str
	 * @return
	 */
	public static final boolean isHyperLink(String str)
	{
		// 是否具有替换符
		if (str.indexOf(combine_replace_end) != -1) {
			return true;
		}
		// 是否具有超链接标签
		if (str.indexOf(combine_mark_end) != -1) {
			return true;
		}
		// 是否具有图片标签
		if (str.indexOf(combine_pic_end) != -1) {
			return true;
		}
		return false;
	}

	public static int getPicNum(String content)
	{
		return getMarkNum(content, combine_pic_start, combine_pic_end);
	}

	public static int getMarkNum(String content, String start, String end)
	{
		int num = 0;
		int startIndex = 0;
		while ((startIndex = content.indexOf(start, startIndex)) != -1) {
			if ((startIndex = content.indexOf(end, startIndex)) != -1) {
				num++;
			}
			else {
				break;
			}
		}
		return num;
	}

	/**
	 * 移除文本中超链接形式的标签，替换符，换行，占位，图片，
	 * 
	 * @param str
	 * @return
	 */
	public static final String removeHyper(String str)
	{
		if (!isHyperLink(str)) {
			return str;
		}
		String temp = str;
		// 替换占位符
		temp = replaceTakenplace(temp);
		// 替换换行服
		temp = removeChangeRow(temp);
		// 替换replace文本
		temp = replaceContent(temp);
		// 去除mark标签
		// 去除图片标签
		temp = removeBracket(temp);
		return temp;
	}

	/**
	 * 去除换行符
	 * 
	 * @param content
	 * @return
	 */
	private static String removeChangeRow(String content)
	{
		while (content.indexOf(TYPE_CONTENT_CHANGEROW) != -1) {
			content = Tools.modifyString(content, TYPE_CONTENT_CHANGEROW, "");
		}
		return content;
	}

	/**
	 * 去除括号'<'/'>'
	 * 
	 * @param content
	 * @return
	 */
	protected static final String removeBracket(String content)
	{
		String start = String.valueOf('<');
		String end = String.valueOf('>');
		String replaceStr = null;//
		String str = "";
		while ((replaceStr = getMiddleString(content, start, end)) != null) {
			content = Tools.modifyString(content, replaceStr, str);
		}
		return content;
	}

	/**
	 * 替换占位符
	 * 
	 * @param string
	 * @return
	 */
	private static final String replaceTakenplace(String content)
	{
		while (content.indexOf(TYPE_CONTENT_TAKEPLACE) != -1) {
			// content = Tools.modifyString(content,TYPE_CONTENT_TAKEPLACE,
			// String.valueOf(NOR_BANK));
			content = Tools.modifyString(content, TYPE_CONTENT_TAKEPLACE, " ");
		}
		return content;
	}

	/**
	 * 将文本中替换标记替换成普通文字
	 * 
	 * @param content
	 * @return
	 */
	public static final String replaceContent(String content)
	{
		String replaceStr = null;// <replace t=1,i=2></replace>
		while ((replaceStr = getMiddleString(content, combine_replace_start, combine_replace_end)) != null) {
			String str = replaceStr(replaceStr);
			content = Tools.modifyString(content, replaceStr, str);
		}
		return content;
	}

	/**
	 * 获得起始字符串到结束字符串内部内容，包含起始与结束
	 * 
	 * @param content
	 * @param startStr
	 * @param endStr
	 * @return
	 */
	protected static String getMiddleString(String content, String startStr, String endStr)
	{
		int startIndex = content.indexOf(startStr);
		if (startIndex == -1) {
			return null;
		}
		int endIndex = content.indexOf(endStr) + endStr.length();
		return content.substring(startIndex, endIndex);
	}

	/**
	 * 将<replace t=1,i=2></replace>转换成字符串 获得type及Id，并将type和Id转换成相应的内容
	 * 
	 * @param replaceStr
	 * @return
	 */
	private static String replaceStr(String replaceStr)
	{
		int type = -1;
		int id = -1;
		int index_equal = 0;//
		int num = 0;
		while ((index_equal = replaceStr.indexOf(NOR_EQUAL, index_equal)) != -1) {
			String value = replaceStr.substring(index_equal + 1, index_equal + 2);
			if (num == 0) {
				type = Integer.parseInt(value);
			}
			else {
				id = Integer.parseInt(value);
			}
			index_equal++;// skip当前
			num++;//
		}
		return replaceStr(type, id);
	}

	/**
	 * 获取替换字符
	 * 
	 * @param type
	 * @param id
	 * @return
	 */
	private static String replaceStr(int type, int id)
	{
		switch (type) {
			case 1:// id
				return String.valueOf(GameManager.getInstance().m_role.m_gameID);
			case 2:// nickName
				return GameManager.getInstance().m_role.m_name;
			case 3:// realm
				int zhenying = GameManager.getInstance().m_role.m_faction;
				if (zhenying < 0 || zhenying >= AbstractGameActor.ROLE_FACTION_LIST.length) {
					return "";
				}
				else {
					return AbstractGameActor.ROLE_FACTION_LIST[zhenying];
				}
			case 4:// family
				if (GameManager.getInstance().m_role.m_family_name == null) {
					return "";
				}
				return GameManager.getInstance().m_role.m_family_name;
			case 5:// career
				return ActorRole.ROLE_VOCATION_LIST[GameManager.getInstance().m_role.m_vocation[GameManager
						.getInstance().m_role.m_vocation.length - 1]];
			case 6:// race
				return ActorRole.ROLE_RACE_LIST[GameManager.getInstance().m_role.m_race];
			case 7:// gender
				int gender = 0;
				String[] strs_female = new String[] { "哥哥", "弟弟", "大哥", "小弟", "师兄", "师弟", "道长", "小伙" };
				String[] strs_male = new String[] { "姐姐", "妹妹", "大姐", "小妹", "师姐", "师妹", "仙姑", "姑娘" };
				if (gender == 0) {
					return strs_female[id - 1];
				}
				else {
					return strs_male[id - 1];
				}
			default:
				return "";
				// throw new IllegalArgumentException("无此类型");
		}
	}

	// /////////////////////////////////

	/**
	 * 获得超链接个数
	 */
	public int getHyperLinkSize()
	{
		if (m_types_hyper == null) {
			return 0;
		}
		return m_types_hyper.length;
	}

	/**
	 * 获得超链接类型数组
	 */
	public char[] getHyperLinkTypes()
	{
		return m_types_hyper;
	}

	/**
	 * 获得超链接id数组
	 */
	public String[] getHyperLinkIds()
	{
		return m_ids_hyper;
	}

	/**
	 * 获得超链接内容数组
	 */
	public String[] getHyperLinkContents()
	{
		return m_contents_hyper;
	}

	/**
	 * 上
	 */
	public void actionOnUp()
	{
		if (m_index_hyper == 0) {
			if (m_relY <= 0) {
				m_relY += H_PRE;
			}
			m_relY = m_relY > 0 ? 0 : m_relY;
		}
		setIndex(getNextIndex(DIR_UP));
	}

	/**
	 * 下
	 */
	public void actionOnDown()
	{
		if (m_index_hyper == getHyperLinkSize() - 1) {
			if (m_relY + getRealHeight() >= m_h) {
				m_relY -= H_PRE;
			}
		}
		setIndex(getNextIndex(DIR_DOWN));
	}

	/**
	 * 左
	 */
	public void actionOnLeft()
	{
//		setIndex(getNextIndex(DIR_LEFT));
		actionOnUp();
	}

	/**
	 * 右
	 */
	public void actionOnRight()
	{
//		setIndex(getNextIndex(DIR_RIGHT));
		actionOnDown();
	}

	/**
	 * 中
	 */
	public int actionOnFire()
	{
		int size = getHyperLinkSize();
		if (size == 0) {
			return -1;
		}
		return m_index_hyper;
	}

	/**
	 * 修改超链接索引
	 * 
	 * @param index_new
	 */
	public void setIndex(int index_new)
	{
		int size = getHyperLinkSize();
		if (size == 0) {
			return;
		}
		if (m_index_hyper == index_new) {
			return;
		}
		m_index_hyper = index_new;
		if (m_index_hyper >= 0 && m_index_hyper < size) {// 有效则修改显示
			correctXY();
		}
	}

	/**
	 * 获得下一方向是否有超链接
	 * 
	 * @param dir
	 * @return
	 */
	private int getNextIndex(int dir)
	{
		int size = getHyperLinkSize();
		if (size == 0) {
			return -1;
		}
		switch (dir) {
			case DIR_UP:
			case DIR_LEFT: {
				if (m_index_hyper == 0) {
					return m_index_hyper;
				}
				return m_index_hyper - 1;
			}
			case DIR_DOWN:
			case DIR_RIGHT: {
				if (m_index_hyper == size - 1) {
					return m_index_hyper;
				}
				return m_index_hyper + 1;
			}
			default:
				// throw new IllegalArgumentException("无此方向");
				return 1;
		}
	}

	// //////////////////////////
	// 绘制方法
	// //////////////////////////

	/**
	 * 直接切割一定区域
	 */
	public void paint(Graphics g, int x, int y)
	{
		int clipX = g.getClipX();
		int clipY = g.getClipY();
		int clipW = g.getClipWidth();
		int clipH = g.getClipHeight();
		g.setClip(x, y, m_w, m_h);
		paintHyperLink(g, x + m_relX, y + m_relY);
		g.setClip(clipX, clipY, clipW, clipH);
	}

	/**
	 * 之前限定了宽高，在相应宽高内设定切割
	 * 
	 * @param g
	 * @param x
	 * @param y
	 */
	public void paintInRect(Graphics g, int x, int y)
	{
		int clipX = g.getClipX();
		int clipY = g.getClipY();
		int clipW = g.getClipWidth();
		int clipH = g.getClipHeight();
		int tempX = x;
		int tempY = y;
		int tempW = m_w;
		int tempH = m_h;
		if (x < clipX) {
			tempX = clipX;
		}
		if (tempY < clipY) {
			tempY = clipY;
		}
		if (tempX + tempW > clipX + clipW) {
			tempW = clipX + clipW - tempX;
		}
		if (tempY + tempH > clipY + clipH) {
			tempH = clipY + clipH - tempY;
		}
		g.setClip(tempX, tempY, tempW, tempH);
		paintHyperLink(g, x + m_relX, y + m_relY);
		g.setClip(clipX, clipY, clipW, clipH);
	}

	// //////////////////////////
	// 抽象方法
	// //////////////////////////
	/**
	 * 根据当前聚焦的超链接修正偏移XY 使聚焦的超链接能全部显示在屏幕范围内
	 */
	protected abstract void correctXY();

	/**
	 * 绘制文本
	 * 
	 * @param g
	 * @param x
	 * @param y
	 */
	public abstract void paintHyperLink(Graphics g, int x, int y);

	// //////////////////////////
	// 属性方法
	// //////////////////////////
	/**
	 * 计算并返回 获得实际的超链接高度
	 */
	public abstract int getRealHeight();

	/**
	 * 超链接高度
	 */
	public int getHeight()
	{
		return m_h;
	}

	/**
	 * 重新设置显示高度
	 * 
	 * @param h
	 */
	public void setH(int h)
	{
		m_h = h;
	}

	/**
	 * 重新设置显示高度
	 * 
	 * @param h
	 */
	public void setPreH(int h)
	{
		H_PRE = h;
	}
}
